using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using dnAnalytics.LinearAlgebra;
using dnAnalytics.LinearAlgebra.IO;
using NUnit.Framework;

namespace dnAnalytics.UnitTests.LinearAlgebra.IO
{
    [TestFixture]
    [Category("Managed")]
    public class MatrixMarketReaderTest
    {
        [Test]
        public void ReadMatrixStringGeneralArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/random_real_general_array_10_20.matrix_market");
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 851.83805;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStreamGeneralArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/random_real_general_array_10_20.matrix_market"));
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 851.83805;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixTextReaderGeneralArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/random_real_general_array_10_20.matrix_market"));
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 851.83805;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStringMatrixGeneralArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/random_real_general_array_10_20.matrix_market", MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 851.83805;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStreamMatrixGeneralArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/random_real_general_array_10_20.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 851.83805;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixTextReaderMatrixGeneralArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/random_real_general_array_10_20.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 851.83805;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStringGeneralCoordinate()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/random_real_general_coordinate_10_20.matrix_market");
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 402.07342;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStreamGeneralCoordinate()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/random_real_general_coordinate_10_20.matrix_market"));
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 402.07342;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixTextReaderGeneralCoordinate()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/random_real_general_coordinate_10_20.matrix_market"));
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 402.07342;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStringMatrixGeneralCoordinate()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/random_real_general_coordinate_10_20.matrix_market", MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 402.07342;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStreamMatrixGeneralCoordinate()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/random_real_general_coordinate_10_20.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 402.07342;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixTextReaderMatrixGeneralCoordinate()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/random_real_general_coordinate_10_20.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(20, matrix.Columns);
            double expected = 402.07342;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStringGeneralSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/hilbert_real_symmetric_array_10.matrix_market");
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(10, matrix.Columns);
            double expected = 1.78552;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStreamGeneralSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/hilbert_real_symmetric_array_10.matrix_market"));
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(10, matrix.Columns);
            double expected = 1.78552;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixTextReaderGeneralSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/hilbert_real_symmetric_array_10.matrix_market"));
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(10, matrix.Columns);
            double expected = 1.78552;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStringMatrixGeneralSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/hilbert_real_symmetric_array_10.matrix_market", MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(10, matrix.Columns);
            double expected = 1.78552;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStreamMatrixGeneralSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/hilbert_real_symmetric_array_10.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(10, matrix.Columns);
            double expected = 1.78552;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixTextReaderMatrixGeneralSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/hilbert_real_symmetric_array_10.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(10, matrix.Rows);
            Assert.AreEqual(10, matrix.Columns);
            double expected = 1.78552;
            double actual = matrix.FrobeniusNorm();
            double error = System.Math.Abs((actual - expected) / expected);
            Assert.IsTrue(error < Constants.IO_ACCEPTABLE_ERROR);
        }

        [Test]
        public void ReadMatrixStringPatternSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/can24_pattern_symmetric_coordinate_24.matrix_market");
            Assert.AreEqual(24, matrix.Rows);
            Assert.AreEqual(24, matrix.Columns);
        }

        [Test]
        public void ReadMatrixStreamPatternSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/can24_pattern_symmetric_coordinate_24.matrix_market"));
            Assert.AreEqual(24, matrix.Rows);
            Assert.AreEqual(24, matrix.Columns);
        }

        [Test]
        public void ReadMatrixTextReaderPatternSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/can24_pattern_symmetric_coordinate_24.matrix_market"));
            Assert.AreEqual(24, matrix.Rows);
            Assert.AreEqual(24, matrix.Columns);
        }

        [Test]
        public void ReadMatrixStringMatrixPatternSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix("../../TestMatrices/can24_pattern_symmetric_coordinate_24.matrix_market", MatrixType.Dense);
            Assert.AreEqual(24, matrix.Rows);
            Assert.AreEqual(24, matrix.Columns);
        }

        [Test]
        public void ReadMatrixStreamMatrixPatternSymmetricArrayc()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(File.OpenRead("../../TestMatrices/can24_pattern_symmetric_coordinate_24.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(24, matrix.Rows);
            Assert.AreEqual(24, matrix.Columns);
        }

        [Test]
        public void ReadMatrixTextReaderMatrixPatternSymmetricArray()
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            Matrix matrix = mmr.ReadMatrix(new StreamReader("../../TestMatrices/can24_pattern_symmetric_coordinate_24.matrix_market"), MatrixType.Dense);
            Assert.AreEqual(24, matrix.Rows);
            Assert.AreEqual(24, matrix.Columns);
        }        
    }
}
